#include <gtest/gtest.h>

#include <memory>

#include "Executor.hpp"
#include "PoseEq.hpp"
namespace adas
{
//测试化用例30：朝东倒车
TEST(ExecutorTest, should_return_x_minus_1_status_is_backward_given_command_is_M_and_facing_is_E)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::CAR));

    //when
    executor->Execute("BM");

    //then
    const Pose target({-1,0,'E'});
    ASSERT_EQ(target,executor->Query());
}
//测试化用例31：朝西倒车
TEST(ExecutorTest, should_return_x_plus_1_status_is_backward_given_command_is_M_and_facing_is_W)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'W'}, CarsType::CAR));

    //when
    executor->Execute("BM");

    //then
    const Pose target({1,0,'W'});
    ASSERT_EQ(target,executor->Query());
}
//测试化用例32：朝北倒车
TEST(ExecutorTest, should_return_y_minus_1_status_is_backward_given_command_is_M_and_facing_is_N)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'N'}, CarsType::CAR));
    //when
    executor->Execute("BM");
    //then
    const Pose target({0,-1,'N'});
    ASSERT_EQ(target,executor->Query());
}
//测试化用例33：朝南倒车
TEST(ExecutorTest, should_return_y_plus_1_status_is_backward_given_command_is_M_and_facing_is_S)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'S'}, CarsType::CAR));
    //when
    executor->Execute("BM");
    //then
    const Pose target({0,1,'S'});
    ASSERT_EQ(target,executor->Query());
}
//测试化用例34：朝东左转倒车
TEST(ExecutorTest, should_return_facing_is_S_status_is_backward_given_command_is_L_and_facing_is_E)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::CAR));
    //when
    executor->Execute("BL");
    //then
    const Pose target({0,0,'S'});
    ASSERT_EQ(target,executor->Query());
}
//测试化用例35：朝西左转倒车
TEST(ExecutorTest, should_return_facing_is_N_status_is_backward_given_command_is_L_and_facing_is_W)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'W'}, CarsType::CAR));
    //when
    executor->Execute("BL");
    //then
    const Pose target({0,0,'N'});
    ASSERT_EQ(target,executor->Query());
}
//测试化用例36：朝北左转倒车
TEST(ExecutorTest, should_return_facing_is_E_status_is_backward_given_command_is_L_and_facing_is_N)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'N'}, CarsType::CAR));
    //when
    executor->Execute("BL");
    //then
    const Pose target({0,0,'E'});
    ASSERT_EQ(target,executor->Query());
}
//测试化用例37：朝南左转倒车
TEST(ExecutorTest, should_return_facing_is_W_status_is_backward_given_command_is_L_and_facing_is_S)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'S'}, CarsType::CAR));
    //when
    executor->Execute("BL");
    //then
    const Pose target({0,0,'W'});
    ASSERT_EQ(target,executor->Query());
}
//测试化用例38：朝东右转倒车
TEST(ExecutorTest, should_return_facing_is_N_status_is_backward_given_command_is_R_and_facing_is_E)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::CAR));
    //when
    executor->Execute("BR");
    //then
    const Pose target({0,0,'N'});
    ASSERT_EQ(target,executor->Query());
}
//测试化用例39：朝西右转倒车
TEST(ExecutorTest, should_return_facing_is_S_status_is_backward_given_command_is_R_and_facing_is_W)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'W'}, CarsType::CAR));
    //when
    executor->Execute("BR");
    //then
    const Pose target({0,0,'S'});
    ASSERT_EQ(target,executor->Query());
}
//测试化用例40：朝北右转倒车
TEST(ExecutorTest, should_return_facing_is_W_status_is_backward_given_command_is_R_and_facing_is_N)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'N'}, CarsType::CAR));
    //when
    executor->Execute("BR");
    //then
    const Pose target({0,0,'W'});
    ASSERT_EQ(target,executor->Query());
}
//测试化用例41：朝南右转倒车
TEST(ExecutorTest, should_return_facing_is_E_status_is_backward_given_command_is_R_and_facing_is_S)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'S'}, CarsType::CAR));
    //when
    executor->Execute("BR");
    //then
    const Pose target({0,0,'E'});
    ASSERT_EQ(target,executor->Query());
}
//测试化用例42：朝东加速倒车
TEST(ExecutorTest, should_return_x_minus_2_status_is_fast_and_backward_given_command_is_M_and_facing_is_E)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::CAR));
    //when
    executor->Execute("FBM");
    //then
    const Pose target({-2,0,'E'});
    ASSERT_EQ(target,executor->Query());
}
//测试化用例43：朝西加速倒车
TEST(ExecutorTest, should_return_x_plus_2_status_is_fast_and_backward_given_command_is_M_and_facing_is_W)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'W'}, CarsType::CAR));
    //when
    executor->Execute("FBM");
    //then
    const Pose target({2,0,'W'});
    ASSERT_EQ(target,executor->Query());
    }
//测试化用例44：朝北加速倒车
TEST(ExecutorTest, should_return_y_minus_2_status_is_fast_and_backward_given_command_is_M_and_facing_is_N)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'N'}, CarsType::CAR));
    //when
    executor->Execute("FBM");
    //then
    const Pose target({0,-2,'N'});
    ASSERT_EQ(target,executor->Query());
}
//测试化用例45：朝南加速倒车
TEST(ExecutorTest, should_return_y_plus_2_status_is_fast_and_backward_given_command_is_M_and_facing_is_S)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'S'}, CarsType::CAR));
    //when
    executor->Execute("FBM");
    //then
    const Pose target({0,2,'S'});
    ASSERT_EQ(target,executor->Query());
}
//测试化用例46：朝东加速左转倒车
TEST(ExecutorTest, should_return_facing_is_S_x_minus_1_status_is_fast_and_backward_given_command_is_L_and_facing_is_E)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::CAR));
    //when
    executor->Execute("FBL");
    //then
    const Pose target({-1,0,'S'});
    ASSERT_EQ(target,executor->Query());
}
//测试化用例47：朝西加速左转倒车
TEST(ExecutorTest, should_return_facing_is_N_x_plus_1_status_is_fast_and_backward_given_command_is_L_and_facing_is_W)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'W'}, CarsType::CAR));
    //when
    executor->Execute("FBL");
    //then
    const Pose target({1,0,'N'});
    ASSERT_EQ(target,executor->Query());
}
//测试化用例48：朝北加速左转倒车
TEST(ExecutorTest, should_return_facing_is_E_y_minus_1_status_is_fast_and_backward_given_command_is_L_and_facing_is_N)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'N'}, CarsType::CAR));
    //when
    executor->Execute("FBL");
    //then
    const Pose target({0,-1,'E'});
    ASSERT_EQ(target,executor->Query());
}
//测试化用例49：朝南加速左转倒车
TEST(ExecutorTest, should_return_facing_is_W_y_plus_1_status_is_fast_and_backward_given_command_is_L_and_facing_is_S)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'S'}, CarsType::CAR));
    //when
    executor->Execute("FBL");
    //then
    const Pose target({0,1,'W'});
    ASSERT_EQ(target,executor->Query());
}
//测试化用例50：朝东加速右转倒车
TEST(ExecutorTest, should_return_facing_is_N_x_minus_1_status_is_fast_and_backward_given_command_is_R_and_facing_is_E)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'E'}, CarsType::CAR));
    //when
    executor->Execute("FBR");

    //then
    const Pose target({-1,0,'N'});
}
//测试化用例51：朝西加速右转倒车
TEST(ExecutorTest, should_return_facing_is_S_x_plus_1_status_is_fast_and_backward_given_command_is_R_and_facing_is_W)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'W'}, CarsType::CAR));
    //when
    executor->Execute("FBR");
    //then
    const Pose target({1,0,'S'});
    ASSERT_EQ(target,executor->Query());
}
//测试化用例52：朝北加速右转倒车
TEST(ExecutorTest, should_return_facing_is_W_y_minus_1_status_is_fast_and_backward_given_command_is_R_and_facing_is_N)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'N'}, CarsType::CAR));
    //when
    executor->Execute("FBR");
    //then
    const Pose target({0,-1,'W'});
    ASSERT_EQ(target,executor->Query());
}
//测试化用例53：朝南加速右转倒车
TEST(ExecutorTest, should_return_facing_is_E_y_plus_1_status_is_fast_and_backward_given_command_is_R_and_facing_is_S)
{
    //given
    std::unique_ptr<Executor> executor(Executor::NewExecutor({0, 0, 'S'}, CarsType::CAR));
    //when
    executor->Execute("FBR");
    //then
    const Pose target({0,1,'E'});
    ASSERT_EQ(target,executor->Query());
}

}